//
//  Status.swift
//  swift-GWYWeiBo
//
//  Created by x on 2017/4/17.
//  Copyright © 2017年 HLB. All rights reserved.
//

import UIKit
private let WB_HOME_TIMELINE = "2/statuses/home_timeline.json"

class Status: NSObject {
    
    /// 创建微博的时间
    var created_at: String? {
        didSet {
            //Mon Apr 24 11:15:33 +0800 2017
            let date = NSDate.dateWithStr(dateStr: created_at!)
            created_at = date.descDate
        }
    }
    
    /// 微博ID
    var id: Int = 0 //如果数据类型是基本数据类型 不赋处置  系统调用init方法是不会给属性分配内存空间
    
    /// 微博信息内容
    var text: String?
    
    /// 微博来源
    var source: String? {
        didSet {
            //<a href=\"http://app.weibo.com/t/feed/5g0B8s\" rel=\"nofollow\">微博weibo.com</a>
            if let str = source {
                if str == "" {
                    return
                }
                // 1.1获取开始截取的位置
                let startLocation = (str as NSString).range(of: ">").location + 1 //放法都是重头查找直至找到一个就停止  也可以倒着来查找
                // 1.2获取截取的长度  倒着来查查询字符串中的某个字符
                let length = (str as NSString).range(of: "<", options: NSString.CompareOptions.backwards).location - startLocation
                // 1.3截取字符串  
                source = "来自:" + (str as NSString).substring(with: NSMakeRange(startLocation, length))
            }
        }
    }
    
    /// 配图数组
    var pic_urls:[[String: AnyObject]]? {
        didSet {
            //初始化储存图片的数组
            cachesImageURLS = [URL]()
            //初始化储存大图的数组
            cachesLargeImageURLS = [URL]()
            for dic in pic_urls! {
                //1.取到图片的字符串地址
                if let urlString = dic["thumbnail_pic"] as? String {
                    //2.把字符串地址转换成url地址
                    let url = URL(string: urlString)
                    //3.把转化好的图片URL地址添加到cachesImageURLS数组中
                    cachesImageURLS?.append(url!)
                    
                    //缩略图: http://wx4.sinaimg.cn/thumbnail/6363b9e1ly1fgzk69rrgbj20qo0qo0vx.jpg
                    //原始图: http://wx4.sinaimg.cn/large/6363b9e1ly1fgzk69rrgbj20qo0qo0vx.jpg
                    let largeString = urlString.replacingOccurrences(of: "thumbnail", with: "large")
                    cachesLargeImageURLS?.append(URL(string: largeString)!)
                }
            }
        }
    }
    
    ///保存微博中所有配图的URL
    var cachesImageURLS:[URL]?
    
    /// 定义一个数组,保存微博所有大图的URL
    var cachesLargeImageURLS:[URL]?
    
    ///用户类型信息
    var user: User?
    
    ///转发微博 (转发微博就就相当与一个微博)
    var retweeted_status: Status?
    
    //如果有转发,原创微博是没有配图的
    ///定义一个计算属性 用于返回原创微博配图的url数组
    var pictureURLS:[URL]? {
        //如果有转发 就返回转发的配图  没有转发就返回原创的配图
        return retweeted_status != nil ? retweeted_status?.cachesImageURLS : cachesImageURLS
    }
    
    /// 定义一个计算属性 用于返回原创还是转发的大图
    var largepictureURLS:[URL]? {
        return retweeted_status != nil ? retweeted_status?.cachesLargeImageURLS : cachesLargeImageURLS
    }
    
    
    //@escaping 逃逸闭包 正闭包可以在函数执行完在执行
    class func loadStatues(since_id:Int, max_id:Int, finished:@escaping (_ statuesModel:[Status]?, _ error: Error?)->()) -> Void {
        
        var param = ["access_token":UserAccess.loadAccount()?.access_token];
        if since_id > 0 {
            //代表是下拉刷新,因为第一次进来是没有值 ,默认传的是0
            param["since_id"] = "\(since_id)"
        }
        if max_id > 0{
            //代表上啦加载
            param["max_id"] = "\(max_id - 1)"
        }
        NetworkTools.shareNetworkTools().get(WB_HOME_TIMELINE, parameters: param, progress: { (_) in
            
        }, success: { (task, JSON) in
            //print(JSON ?? 9)
            //1.解析获取的所有数据
            let dic = JSON as? [String: AnyObject]
            if let tt = dic?["statuses"] as? [[String: AnyObject]]{
                //1得到数据模型之后我们应该把数据模型传递到主界面显示
                let models = Status.statue(models: tt)
                //3.保存微博配图 类方法中特只能调用类方法
                cachesStatuesImages(list: models, finished: finished)
                
                //2.通过闭包把数据模型传递给调用者  这里应该等图片全部缓存完毕了 在通过闭包把数据传递给通知者
                //finished(models, nil)
            }
        }) { (_, error) in
            print(error);
            finished(nil, error);
        }
    }
    
    /// 缓存微博的配图
    ///
    /// - Parameter list: <#list description#>
    class func cachesStatuesImages(list: [Status], finished:@escaping (_ statuesModel:[Status]?, _ error: Error?)->() ) -> Void {
        //如果你下拉刷新没有新的数据的时候,防止出现Bug我们就不用在执行下面的操作 直接回调
        if list.count == 0 {
            finished(list, nil)
            return
        }
        //thumbnail_pic图片地址的key
        //由于图片在在是异步的  我们要等图片全部下载完毕之后才可已通知
        //1.创建一个队列数组
        let downloadQueue = DispatchGroup()
        //print("abc".cacheDir())
        for modle in list {
            //swift新语法  = 如果这个数组没有值 则执行else后面的语句 相当于if
//            guard let urls = model.cachesImageURLS {
//                continue
//            }
            //有的微博模型里面没有图片 所以数组没有初始化  数组为nil 所以要判断数组是不是nil
            if modle.pictureURLS != nil {
                for url in modle.pictureURLS! {
                    //2.要把下载图片的线程加到队列数组中
                    downloadQueue.enter()
                    //在这里开始缓存图片  SDWebImage下载图片会自动帮你缓存到内存和磁盘中
                    SDWebImageManager.shared().downloadImage(with: url, options: SDWebImageOptions.init(rawValue: 0), progress: nil, completed: { (_, _, _, _, _) in
                        //print("图片已经缓存完毕")
                        //下载完成之后吧离开当前组
                        downloadQueue.leave()
                    })
                }
            }
        }
        downloadQueue.notify(queue: DispatchQueue.main) { 
    //print("所有图片缓存完成");
            //能来到这个证明所有的微博图片已经缓存完成了
            //2.等图片都下载完毕了之后 我们在通知调用者把这个数据传递个调用者
            finished(list, nil)
        };
    }
    /// 字典转数据模型数组
    ///
    /// - Returns: <#return value description#>
    class func statue(models: [[String: AnyObject]]) -> [Status] {
        var model = [Status]()//加载一个可变数组
        for dict in models {
            //每个元素都是一个数组
            model.append(Status.init(dict: dict))
        }
        return model
    }
    
    /// 字典转模型数组
    ///
    /// - Parameter dict: 要转换的字典
    init(dict: [String: AnyObject]) {
        super.init() //使用KVC必须要代用init方法的原因: 调用init方法给属性分配存储空间  然后才能赋值 不然报错啊
        setValuesForKeys(dict)
    }
    
    //拦截KVC的方法 给用户信息赋值
    override func setValue(_ value: Any?, forKey key: String) {
        super.setValue(value, forKey: key)
        
        //1.判断是不是user这个字段
        if "user" == key {
            user = User(dict: value as! [String: AnyObject])
        }
        
        //2.判断是不是转发微博这个字段
        if "retweeted_status" == key {
            retweeted_status = Status(dict: value as! [String: AnyObject])
            return
        }
    }
    
    //使用KVC遇到的不认识的Key 就会执行这个方法  不会报错
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
        
    }
    
    /// 打印modle数据模型
    let tt = ["created_at","id","text","source","pic_urls","user"]
    override var description: String {
        
        let dic = dictionaryWithValues(forKeys: tt)
        return "\(dic)"
    }
    
    
    
    
    
    
}
